import { isArray } from '../share'

const regTagBlock = /<.*(?<!.*>.*)>/
const regEndTag = /(^< *\/)|(\/ *>$)/
const regStartTagName = /^< *([a-z]+[0-9\-a-z]*)/i
const regAttr =
  /(?<name>[:@]{0,1}[a-z]+[0-9\-a-z]*) *=? *((?<fen>['"])(?<value>[0-9\-a-z :;#]*)\k<fen>)?/i
const regMustache = /\{\{(.*(?<!.*\}.*))\}\}/

export function compileTemplate(template) {
  function go(length) {
    const text = template.substring(0, length)
    template = template.substring(length)
    return text
  }
  function matchStartTag(tagBlock) {
    const [startTagBlock, startTagName] = tagBlock.match(regStartTagName)
    return [startTagName, tagBlock.substring(startTagBlock.length)]
  }
  function matchAttrs(tagBlock) {
    const props = Object.create(null)
    while (tagBlock) {
      const match = tagBlock.match(regAttr)
      if (match) {
        const attr = match[0],
          groups = match.groups
        tagBlock = tagBlock.substring(match.index + attr.length)
        if (groups) {
          let { name, value } = groups
          // 属性变量
          if (name.startsWith(':') && value) {
            name = name.substring(1)
            value = {
              value,
              directive: true
            }
          }
          // 事件变量
          if (name.startsWith('@') && value) {
            name = name.substring(1)
            value = {
              value,
              event: true
            }
          }
          props[name] = value || true
        }
      } else {
        tagBlock = null
      }
    }
    return props
  }
  function matchTextChildren(text) {
    const children = []
    while (text) {
      const match = text.match(regMustache)
      if (match) {
        const [mustashBlock, name] = match,
          index = match.index
        // 表达式前面的静态文本
        children.push(text.substring(0, index))
        // 表达式
        children.push({
          text: { value: name, express: true }
        })
        text = text.substring(mustashBlock.length + index)
      } else {
        children.push(text)
        text = null
      }
    }
    return children
  }
  function pushChildren(children) {
    const parent = stack[stack.length - 1]
    if (!isArray(children)) {
      children = [children]
    }
    // 父子结构，stack中最后一项是父
    if (parent) {
      parent.children.push(...children)
    }
    return parent
  }
  function matchTag() {
    // 提取标签
    const tagBlockMatch = template.match(regTagBlock)
    if (tagBlockMatch) {
      const [tagBlock] = tagBlockMatch
      const textChild = template.substring(0, tagBlockMatch.index)
      // 处理文本节点，里面可能有响应式变量或表达式等
      const children = matchTextChildren(textChild)
      pushChildren(children)
      // 开始、结束标签
      if (!regEndTag.test(tagBlock)) {
        // 开始 -> 提取标签名和属性
        var [tag, tagRightBlock] = matchStartTag(tagBlock)
        // 处理属性，里面可能有响应式变量和自定义事件
        const props = matchAttrs(tagRightBlock)
        const node = {
          tag,
          props,
          children: []
        }
        const parent = pushChildren(node)
        // 获取根节点
        if (!parent) {
          root = node
        }
        stack.push(node)
      } else {
        // 结束标签直接弹出
        stack.pop()
      }
      go(tagBlock.length)
    } else {
      // 没匹配到标签，就走完
      template = null
    }
  }
  let root = null
  const stack = []
  while (template) {
    matchTag()
  }
  console.log('root', root)
  return root
}
